package com.cartrentalsystem.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cartrentalsystem.domain.po.Car;
import com.cartrentalsystem.domain.po.Rental;
import com.cartrentalsystem.domain.po.Repair;
import com.cartrentalsystem.domain.vo.RepairVo;
import com.cartrentalsystem.domain.vo.Result;
import com.cartrentalsystem.mapper.RepairMapper;
import com.cartrentalsystem.service.ICarService;
import com.cartrentalsystem.service.IEmployeeService;
import com.cartrentalsystem.service.IRentalService;
import com.cartrentalsystem.service.IRepairService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author LHD
 * @since 2025-06-16
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class RepairServiceImpl extends ServiceImpl<RepairMapper, Repair> implements IRepairService {

    private final IEmployeeService employeeService;

    private final ICarService carService;

    private final IRentalService rentalService;

    @Override
    public Result<Page<RepairVo>> pageList(Integer page, Integer size, Integer status, String employeeName){
        Page<Repair> list = this.lambdaQuery()
                .eq(status != null, Repair::getStatus, status)
                .eq(Repair::getDeleted, 0)
                .page(Page.of(page, size));
        List<RepairVo> repairVos = new ArrayList<>(list.getRecords().size());
        for (Repair repair : list.getRecords()) {
            RepairVo repairVo = new RepairVo();
            BeanUtils.copyProperties(repair, repairVo);
            repairVo.setEmployeeName(employeeService.getById(repair.getEmployeeId()).getName());
            repairVo.setCarInfo(carService.getById(repair.getCarId()).getBrand()+carService.getById(repair.getCarId()).getModel()+" "+carService.getById(repair.getCarId()).getPlateNumber());
            repairVos.add(repairVo);
        }
        Page<RepairVo> pageInfoVo = new Page<>(page, size);
        pageInfoVo.setRecords(repairVos);
        pageInfoVo.setTotal(list.getTotal());
        log.info("page: {}, size: {}, total: {}, records: {}", page, size, list.getRecords().size(), repairVos);
        log.info("pageInfoVo: {}", pageInfoVo);
        return Result.success(pageInfoVo);
    }


    @Override
    @Transactional
    public boolean insertRepair(Integer carId, String repairReason, Double repairMoney, String employeeName){
        Repair repair = new Repair();
        repair.setCarId(carId);
        repair.setRepairReason(repairReason);
        repair.setRepairMoney(repairMoney);
        repair.setEmployeeId(employeeService.getIdByNameAndRole(employeeName,2));
        repair.setStatus(0);
        repair.setDeleted(0);

        Integer rentalId = rentalService.getRentalIdByCarId(carId);
        repair.setRentalId(rentalId);

        // 添加租赁总金额和还车日期
        LocalDate now = LocalDate.now();
        rentalService.lambdaUpdate()
                .eq(Rental::getId, rentalId)
                .setSql("money = money + " + repairMoney+", real_return_time = '"+now+"'")
                .update();


        int insert = this.baseMapper.insert(repair);
        if (insert > 0){
            return true;
        }
        else {
            return false;
        }
    }

    @Override
    @Transactional
    public boolean updateRepairing(Integer id, LocalDate repairTime, LocalDate repairExpectFinishTime){
        boolean update = this.lambdaUpdate()
                .eq(Repair::getId, id)
                .eq(Repair::getDeleted, 0)
                .set(Repair::getRepairTime, repairTime)
                .set(Repair::getRepairExpectFinishTime, repairExpectFinishTime)
                .set(Repair::getStatus, 1)
                .update();
        return update;
    }

    @Override
    @Transactional
    public boolean updateRepaired(Integer id){
        LocalDate now = LocalDate.now();
        boolean update = this.lambdaUpdate()
                .eq(Repair::getId, id)
                .eq(Repair::getDeleted, 0)
                .set(Repair::getStatus, 2)
                .set(Repair::getRepairRealFinishTime, now)
                .update();

        Repair repair = this.lambdaQuery()
                .eq(Repair::getId, id)
                .eq(Repair::getDeleted, 0)
                .one();

        // rental的status要变为2
        rentalService.lambdaUpdate()
                .eq(Rental::getId, repair.getRentalId())
                .eq(Rental::getDeleted, 0)
                .set(Rental::getStatus, 2)
                .update();


        // car的status要变为1
        carService.lambdaUpdate()
                .eq(Car::getId, repair.getCarId())
                .eq(Car::getDeleted, 0)
                .set(Car::getStatus, 1)
                .update();

        return update;
    }

}
